﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using SharpMap.Presentation.Wpf;
using SharpMap.Layers;
using System.Diagnostics;
using SharpMap.Styles;
using IO = System.IO;
using System.Reflection;
namespace SharpMap.Wpf
{

    public class MapLayer : ItemsControl
    {
        static readonly IValueConverter _strignToLayerConverter = new SharpMap.Wpf.Converters.StringLayerSourceConverter();


        #region Layer Style Convenience properties



        public StyleColor Fill
        {
            get { return (StyleColor)GetValue(FillProperty); }
            set { SetValue(FillProperty, value); }
        }
        public static readonly DependencyProperty FillProperty =
            DependencyProperty.Register("Fill", typeof(StyleColor), typeof(MapLayer),
            new UIPropertyMetadata(default(StyleColor), LayerStylePropertyChanged));




        public IStyle LayerStyle
        {
            get { return (IStyle)GetValue(LayerStyleProperty); }
            set { SetValue(LayerStyleProperty, value); }
        }
        public static readonly DependencyProperty LayerStyleProperty =
            DependencyProperty.Register("LayerStyle", typeof(IStyle), typeof(MapLayer), new UIPropertyMetadata(default(IStyle)));


        
        
        
        #endregion


        public static readonly RoutedEvent LayerChangedEvent =
            EventManager.RegisterRoutedEvent("LayerChanged", RoutingStrategy.Bubble
                                            , typeof(RoutedEventHandler), typeof(MapLayer));




        //TODO: should be binding actually, but currnetly there is a problem with ambigues match,
        // due to hiding the Style property in the lyers hirarchy
        static void LayerStylePropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
        {
            MapLayer This = target as MapLayer;
            if (This != null && This.Layer != null)
            {
                This.WireUp();
            }
        }

        private void WireUp()
        {
        //    Binding b = new Binding("Style");
        //    //b.Source = _iLayer;
        //    b.Mode = BindingMode.TwoWay;
        //    SetBinding(LayerStyleProperty, b);
        }

        public event RoutedEventHandler LayerChanged
        {
            add
            {
                AddHandler(LayerChangedEvent, value);
            }
            remove
            {
                RemoveHandler(LayerChangedEvent, value);
            }
        }

        public string Source
        {
            get { return (string)GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); }
        }
        public static readonly DependencyProperty SourceProperty =
            DependencyProperty.Register("Source", typeof(string), typeof(MapLayer),
            new UIPropertyMetadata(default(string), SourcePropertyChanged));




        static void SourcePropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
        {
            MapLayer This = target as MapLayer;
            if (This != null)
            {
                This.handleSourceChanged(e);
            }
        }

        private void handleSourceChanged(DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue is string)
            {
                CleanUpCurentContent();
                object layer = LoadLayerFromFile(e.NewValue as string);
                _iLayer = layer as ILayer;
                _iLayer.Style = LayerStyle;
                if (_iLayer != null)
                {
                    //Binding b = new Binding("Style");
                    //b.Source = _iLayer;
                    //b.Mode = BindingMode.OneWayToSource;
                    //SetBinding(MapLayer.LayerStyleProperty, b);
                    //RaiseEvent(MapControl.
                    RaiseEvent(new RoutedEventArgs(LayerChangedEvent));
                }
            }
        }

        private object LoadLayerFromFile(string fileName)
        {
            string fullFileName;
            if (IO.Path.IsPathRooted(fileName))
            {
                fullFileName = fileName;
            }
            else
            {
                Assembly entryAssembly = Assembly.GetEntryAssembly();
                string exeDir = IO.Path.GetDirectoryName(entryAssembly.Location);
                fullFileName = IO.Path.Combine(exeDir, fileName);
            }

            SharpMap.Data.Providers.ShapeFile.ShapeFileProvider shapFile =
                    new SharpMap.Data.Providers.ShapeFile.ShapeFileProvider(fullFileName);
            String layerName = IO.Path.GetFileNameWithoutExtension(fileName);

            SharpMap.Layers.GeometryLayer layer = new SharpMap.Layers.GeometryLayer(layerName, shapFile);
            return layer;
        }

        private void CleanUpCurentContent()
        {
            //TODO: implement
        }



        static MapLayer()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(MapLayer), new FrameworkPropertyMetadata(typeof(MapLayer)));
        }

        public MapLayer()
        {
        }

        internal void PrapareMapLayer(object item)
        {

        }

        DrawingLayer _drawingLayer;
        ILayer _iLayer;

        public ILayer Layer
        {
            get { return _iLayer; }
            set { _iLayer = value; }
        }


    }
}
